/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cstdlib>
#include <gtest/gtest.h>
#include "dal/config_loader.h"
#include "dal/ret_type.h"
#include "dds/dds.h"
#include "dds/ddsi/ddsi_xqos.h"
#include "dds/ddsrt/environ.h"

TEST(config_loader_api_takes_effect, config_loader)
{
    dds_return_t c_ret;
    dal_ret_t ret = DAL_RETCODE_ERROR;

    setenv("DAL_CONFIG_PATH", "./dal_cyclonedds_config_2.xml", 1);
    ret = dal_load_config_from_path("./dal_cyclonedds_config.xml", nullptr);
    EXPECT_EQ(ret, DAL_RETCODE_OK);
    EXPECT_STREQ(getenv("CYCLONEDDS_URI"), "./dal_cyclonedds_config.xml");

    const char *config = NULL;
    ddsrt_getenv("CYCLONEDDS_URI", &config);
    dds_entity_t domain_from_conf = dds_create_domain(23, config);
    EXPECT_GT(domain_from_conf, 0);

    dds_domainid_t id = -1;
    dds_get_domainid(domain_from_conf, &id);
    EXPECT_EQ(id, 23);

    dds_entity_t participant = dds_create_participant(23, NULL, NULL);
    EXPECT_GT(participant, 0);

    dds_qos_t* p_qos = dds_create_qos();
    c_ret = dds_get_qos(participant, p_qos);
    EXPECT_EQ(c_ret, DDS_RETCODE_OK);

    char* name = new char[256];
    memset(name, 0, 256);
    dds_qget_entity_name(p_qos, &name);
    EXPECT_NE(strlen(name), 0) << "entity name: " << name;

    delete [] name;

    EXPECT_EQ(dds_delete(participant), DDS_RETCODE_OK);
    EXPECT_EQ(dds_delete(domain_from_conf), DDS_RETCODE_OK);

    dds_delete_qos(p_qos);
}

TEST(config_file_env_take_effect, config_loader)
{
    dds_return_t c_ret;
    dal_ret_t ret = DAL_RETCODE_ERROR;

    setenv("DAL_CONFIG_PATH", "./dal_cyclonedds_config.xml", 1);
    ret = dal_load_config_from_path("./dal_cyclonedds_config_3.xml", nullptr);
    EXPECT_EQ(ret, DAL_RETCODE_OK);
    EXPECT_STREQ(getenv("CYCLONEDDS_URI"), "./dal_cyclonedds_config.xml");

    const char *config = NULL;
    ddsrt_getenv("CYCLONEDDS_URI", &config);
    dds_entity_t domain_from_conf = dds_create_domain(23, config);
    EXPECT_GT(domain_from_conf, 0);

    dds_domainid_t id = -1;
    dds_get_domainid(domain_from_conf, &id);
    EXPECT_EQ(id, 23);

    dds_entity_t participant = dds_create_participant(23, NULL, NULL);
    EXPECT_GT(participant, 0);

    dds_qos_t* p_qos = dds_create_qos();
    c_ret = dds_get_qos(participant, p_qos);
    EXPECT_EQ(c_ret, DDS_RETCODE_OK);

    char* name = new char[256];
    memset(name, 0, 256);
    dds_qget_entity_name(p_qos, &name);
    EXPECT_NE(strlen(name), 0) << "entity name: " << name;

    delete [] name;

    EXPECT_EQ(dds_delete(participant), DDS_RETCODE_OK);
    EXPECT_EQ(dds_delete(domain_from_conf), DDS_RETCODE_OK);

    dds_delete_qos(p_qos);
}

TEST(config_loader_not_takes_effect, config_loader)
{
    dds_return_t c_ret;
    dal_ret_t ret = DAL_RETCODE_ERROR;

    unsetenv("CYCLONEDDS_URI");
    setenv("DAL_CONFIG_PATH", "./dal_cyclonedds_config_3.xml", 1);
    ret = dal_load_config_from_path("./dal_cyclonedds_config_3.xml", nullptr);
    EXPECT_EQ(ret, DAL_RETCODE_ERROR);
    EXPECT_STREQ(getenv("CYCLONEDDS_URI"), NULL);

    const char *config = NULL;
    ddsrt_getenv("CYCLONEDDS_URI", &config);
    dds_entity_t domain_from_conf = dds_create_domain(24, config);
    EXPECT_GT(domain_from_conf, 0);

    dds_domainid_t id = -1;
    dds_get_domainid(domain_from_conf, &id);
    EXPECT_EQ(id, 24);

    dds_entity_t participant = dds_create_participant(24, NULL, NULL);
    EXPECT_GT(participant, 0);

    dds_qos_t* p_qos = dds_create_qos();
    c_ret = dds_get_qos(participant, p_qos);
    EXPECT_EQ(c_ret, DDS_RETCODE_OK);

    char* name = new char[256];
    memset(name, 0, 256);
    dds_qget_entity_name(p_qos, &name);
    EXPECT_EQ(strlen(name), 0);

    delete [] name;

    EXPECT_EQ(dds_delete(participant), DDS_RETCODE_OK);
    EXPECT_EQ(dds_delete(domain_from_conf), DDS_RETCODE_OK);

    dds_delete_qos(p_qos);
}